import * as Cesium from "cesium";

class CreateFrustum {
    constructor(viewer, options) {
        if (CreateFrustum.instance) {
            return CreateFrustum.instance.updateInstance(options);
        }

        this.viewer = viewer;
        this.position = options.position;
        this.orientation = options.orientation;
        this.fov = options.fov || 30;
        this.near = options.near || 1;
        this.far = options.far || 100;
        this.aspectRatio = options.aspectRatio || 1;
        
        this.add();
        CreateFrustum.instance = this;
    }

    // 更新实例属性
    updateInstance(options) {
        this.position = options.position || this.position;
        this.orientation = options.orientation || this.orientation;
        this.fov = options.fov || this.fov;
        this.near = options.near || this.near;
        this.far = options.far || this.far;
        this.aspectRatio = options.aspectRatio || this.aspectRatio;
        
        this.add();
        return this;
    }

    // 更新视锥体的姿态
    update(position, orientation) {
        this.position = position;
        this.orientation = orientation;
        this.add();
    }

    // 创建视锥体和轮廓线
    add() {
        this.clear();
        this.addFrustum();
        this.addOutline();
    }

    // 清除视锥体和轮廓线
    clear() {
        this.clearFrustum();
        this.clearOutline();
    }

    // 清除视锥体
    clearFrustum() {
        if (this.frustumPrimitive) {
            this.viewer.scene.primitives.remove(this.frustumPrimitive);
            this.frustumPrimitive = null;
        }
    }

    // 清除轮廓线
    clearOutline() {
        if (this.outlinePrimitive) {
            this.viewer.scene.primitives.remove(this.outlinePrimitive);
            this.outlinePrimitive = null;
        }
    }

    // 创建视锥体
    addFrustum() {
        let frustum = new Cesium.PerspectiveFrustum({
            fov: Cesium.Math.toRadians(this.fov),
            aspectRatio: this.aspectRatio,
            near: this.near,
            far: this.far,
        });
        let geometry = new Cesium.FrustumGeometry({
            frustum: frustum,
            origin: this.position,
            orientation: this.orientation,
            vertexFormat: Cesium.VertexFormat.POSITION_ONLY,
        });
        let instance = new Cesium.GeometryInstance({
            geometry: geometry,
            attributes: {
                color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                    new Cesium.Color(152 / 255, 255 / 255, 152 / 255, 0.1)
                )
            }
        });
        let primitive = new Cesium.Primitive({
            geometryInstances: instance,
            appearance: new Cesium.PerInstanceColorAppearance({
                closed: true,
                flat: true,
            }),
            asynchronous: false,
        });
        this.frustumPrimitive = this.viewer.scene.primitives.add(primitive);
    }

    // 创建轮廓线
    addOutline() {
        let frustum = new Cesium.PerspectiveFrustum({
            fov: Cesium.Math.toRadians(this.fov),
            aspectRatio: this.aspectRatio,
            near: this.near,
            far: this.far,
        });
        let geometry = new Cesium.FrustumOutlineGeometry({
            frustum: frustum,
            origin: this.position,
            orientation: this.orientation,
            vertexFormat: Cesium.VertexFormat.POSITION_ONLY,
        });
        let instance = new Cesium.GeometryInstance({
            geometry: geometry,
            attributes: {
                color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                    new Cesium.Color(152 / 255, 255 / 255, 152 / 255, 1.0)
                )
            }
        });
        let primitive = new Cesium.Primitive({
            geometryInstances: instance,
            appearance: new Cesium.PerInstanceColorAppearance({
                closed: true,
                flat: true,
            }),
            asynchronous: false,
        });
        this.outlinePrimitive = this.viewer.scene.primitives.add(primitive);
    }

    // 静态方法：获取单例实例
    static getInstance(viewer, options) {
        if (!CreateFrustum.instance && viewer) {
            return new CreateFrustum(viewer, options);
        }
        return CreateFrustum.instance.updateInstance(options);
    }

    // 静态方法：销毁单例实例
    static destroyInstance() {
        if (CreateFrustum.instance) {
            CreateFrustum.instance.clear();
            CreateFrustum.instance = null;
        }
    }
}

// 初始时实例为空
CreateFrustum.instance = null;

export default CreateFrustum;